package com.example.aipDriver.service;

import com.example.aipDriver.remote.ServiceDriverUserClient;
import com.example.aipDriver.remote.ServiceVerificationCodeClient;
import com.example.internalcommon.constant.CommonStatusEnum;
import com.example.internalcommon.constant.DriverCarConstants;
import com.example.internalcommon.constant.IdentityConstants;
import com.example.internalcommon.constant.TokenConstants;
import com.example.internalcommon.dto.ResponseResult;
import com.example.internalcommon.dto.TokenResponse;
import com.example.internalcommon.request.VerificationCodeDTO;
import com.example.internalcommon.response.DriverUserExistsResponse;
import com.example.internalcommon.response.NumberCodeResponse;
import com.example.internalcommon.util.JwtUtils;
import com.example.internalcommon.util.RedisPrefixUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

/**
 * @Author lyra
 * @Date 2023/4/14 17:27
 **/
@Service
@Slf4j
public class VerificationCodeService {

    @Autowired
    ServiceDriverUserClient serviceDriverUserClient;

    @Autowired
    ServiceVerificationCodeClient serviceVerificationCodeClient;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    public ResponseResult checkAndSendVerification(String driverPhone) {
        // (1)查询 service-driver-user,该手机号的司机是否存在
        ResponseResult<DriverUserExistsResponse> driverUserExistsResponseResponseResult = serviceDriverUserClient.checkDriver(driverPhone);
        DriverUserExistsResponse data = driverUserExistsResponseResponseResult.getData();
        int ifExists = data.getIfExists();
        if (ifExists == DriverCarConstants.DRIVER_NOT_EXISTS) {
            return ResponseResult.fail(CommonStatusEnum.DRIVER_NOT_EXISTS.getCode(), CommonStatusEnum.DRIVER_NOT_EXISTS.getValue());
        }
        log.info(driverPhone + " 的司机存在");

        // (2)获取验证码
        ResponseResult<NumberCodeResponse> numberCodeResult = serviceVerificationCodeClient.getNumberCode(6);
        NumberCodeResponse numberCodeResponse = numberCodeResult.getData();
        int numberCode = numberCodeResponse.getNumberCode();
        log.info("验证码" + numberCode);

        // (3)调用第三方发送验证码 阿里短信,腾讯,华信,容联


        // (4)存入redis 1.生成key 2.存入value
        String key = RedisPrefixUtils.generatorKeyByPhone(driverPhone, IdentityConstants.DRIVER_IDENTITY);
        stringRedisTemplate.opsForValue().set(key, numberCode + "", 2, TimeUnit.MINUTES);

        return ResponseResult.success("");
    }

    /**
     * 3.校验验证码
     * 验证通过,生成token到前端
     * 客户端想要访问服务器controller,必须携带token,如果没有token,只能访问不需要token也能访问的页面
     * MODIFY
     * 修改为双token验证
     *
     * @param driverPhone   手机号
     * @param verificationCode 验证码
     * @return
     */
    public ResponseResult checkCode(String driverPhone, String verificationCode) {
        // (1)根据手机号去redis读取验证码
        // 生成key
        String key = RedisPrefixUtils.generatorKeyByPhone(driverPhone,IdentityConstants.DRIVER_IDENTITY);
        // 根据key获取value
        String codeRedis = stringRedisTemplate.opsForValue().get(key);
        System.out.println("redis中的value:" + codeRedis);

        // (2)校验验证码
        // 验证码是否存在
        System.out.println("校验验证码");
        if (StringUtils.isBlank(codeRedis)) {
            return ResponseResult.fail(CommonStatusEnum.VERIFICATION_CODE_ERROR.getCode()
                    , CommonStatusEnum.VERIFICATION_CODE_ERROR.getValue());
        }
        // 验证码和redis中的值是否相等
        if (!verificationCode.trim().equals(codeRedis.trim())) {
            System.out.println("不相等");
            return ResponseResult.fail(CommonStatusEnum.VERIFICATION_CODE_ERROR.getCode()
                    , CommonStatusEnum.VERIFICATION_CODE_ERROR.getValue());
        }

/*        // (3)判断原来是否有用户,并进行相应的处理
        System.out.println("判断原来是否有用户,并进行相应的处理");
        VerificationCodeDTO verificationCodeDTO = new VerificationCodeDTO();
        verificationCodeDTO.setPassengerPhone(driverPhone);
        serviceDriverUserClient.loginOrRegister(verificationCodeDTO);*/

        // (4)颁发令牌,不应该用魔法值(未先预定的值),用常量
        String accessToken = JwtUtils.generatorToken(driverPhone, IdentityConstants.DRIVER_IDENTITY, TokenConstants.ACCESS_TOKEN_TYPE);
        System.out.println("颁发令牌");
        String refreshToken = JwtUtils.generatorToken(driverPhone,IdentityConstants.DRIVER_IDENTITY, TokenConstants.REFRESH_TOKEN_TYPE);

        // (5)将token 存储到redis当中
        String accessTokenKey = RedisPrefixUtils.generatorTokenKey(driverPhone, IdentityConstants.DRIVER_IDENTITY,TokenConstants.ACCESS_TOKEN_TYPE);
        stringRedisTemplate.opsForValue().set(accessTokenKey, accessToken, 30, TimeUnit.DAYS);
        // stringRedisTemplate.opsForValue().set(accessTokenKey, accessToken, 5, TimeUnit.SECONDS);

        String refreshTokenKey = RedisPrefixUtils.generatorTokenKey(driverPhone, IdentityConstants.DRIVER_IDENTITY,TokenConstants.REFRESH_TOKEN_TYPE);
        stringRedisTemplate.opsForValue().set(refreshTokenKey, accessToken, 31, TimeUnit.DAYS);
        // stringRedisTemplate.opsForValue().set(refreshTokenKey, accessToken, 5, TimeUnit.MINUTES);

        // 响应
        TokenResponse tokenResponse = new TokenResponse();
        tokenResponse.setAccessToken(accessToken);
        tokenResponse.setRefreshToken(refreshToken);
        return ResponseResult.success(tokenResponse);
    }
}
